package com.study.crypto.basic.gb.common;

import org.apache.ibatis.session.RowBounds;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import java.util.List;

/**
 * 通用 Service，子类继承可以直接使用对应通用 Mapper 的方法
 * @author Songjin
 * @since 2019年3月12日 下午1:03:09
 */
public class GeneralService<T> {
	
	protected Logger logger = LoggerFactory.getLogger(this.getClass());
	
	@Autowired
	protected GeneralMapper<T> mapper;
	
	/**
	 * 根据实体属性作为条件进行删除，查询条件使用等号
	 * @param record 记录
	 * @return 受影响行数
	 */
	public int delete(T record) {
		logger.warn("'delete'删除记录: {}", record);
		return mapper.delete(record);
	}
	
	/**
	 * 根据Example条件删除数据
	 * @param example 删除的条件example
	 * @return 受影响行数
	 */
	public int deleteByExample(Object example) {
		logger.warn("'deleteByExample'使用example删除记录: {}", example);
		return mapper.deleteByExample(example);
	}
	
	/**
	 * 根据主键字段进行删除，方法参数必须包含完整的主键属性
	 * @param key 主键
	 * @return 受影响行数
	 */
	public int deleteByPrimaryKey(Object key) {
		logger.warn("'deleteByPrimaryKey'使用主键删除记录: {}", key);
		return mapper.deleteByPrimaryKey(key);
	}
	
	/**
	 * 根据主键字段查询总数，方法参数必须包含完整的主键属性，查询条件使用等号
	 * @param key 主键
	 * @return 存在true，不存在false
	 */
	public boolean existsWithPrimaryKey(Object key) {
		logger.info("'existsWithPrimaryKey'判断主键: {} 数据是否存在", key);
		return mapper.existsWithPrimaryKey(key);
	}
	
	/**
	 * 保存一个实体，null的属性也会保存，不会使用数据库默认值
	 * @param record 记录
	 * @return 受影响行数
	 */
	public int insert(T record) {
		logger.info("'insert'新增记录: {}", record);
		return mapper.insert(record);
	}
	
	/**
	 * 保存一个实体，null的属性不会保存，会使用数据库默认值
	 * @param record 记录
	 * @return 受影响行数
	 */
	public int insertSelective(T record) {
		logger.info("'insertSelective'新增记录: {}", record);
		return mapper.insertSelective(record);
	}
	
	/**
	 * MySQL 批量新增记录
	 * @param records 记录集合
	 * @return 受影响行数
	 */
	public int insertList(List<T> records) {
		logger.info("'insertList'批量新增记录: {}", records);
		return mapper.insertList(records);
	}
	
	/**
	 * 根据实体中的属性值进行查询，查询条件使用等号
	 * @param record 记录
	 * @return 记录集合
	 */
	public List<T> select(T record) {
		logger.info("'select'根据条件查询集合: {}", record);
		return mapper.select(record);
	}
	
	/**
	 * 查询全部结果
	 * @return 记录集合
	 */
	public List<T> selectAll() {
		logger.info("'selectAll'查询全部记录");
		return mapper.selectAll();
	}
	
	/**
	 * 根据Example条件进行查询
	 * @param example 条件
	 * @return 记录集合
	 */
	public List<T> selectByExample(Object example) {
		logger.info("'selectByExample'使用example查询集合");
		return mapper.selectByExample(example);
	}
	
	/**
	 * 根据example条件和RowBounds进行分页查询
	 * @param example   查询条件
	 * @param rowBounds 分页条件
	 * @return 记录集合
	 */
	public List<T> selectByExampleAndRowBounds(Object example, RowBounds rowBounds) {
		logger.info("'selectByExampleAndRowBounds'分页查询: {}, {}", example, rowBounds);
		return mapper.selectByExampleAndRowBounds(example, rowBounds);
	}
	
	/**
	 * 根据主键字段进行查询，方法参数必须包含完整的主键属性，查询条件使用等号
	 * @param key 主键
	 * @return 记录
	 */
	public T selectByPrimaryKey(Object key) {
		logger.info("'selectByPrimaryKey'主键查询: {}", key);
		return mapper.selectByPrimaryKey(key);
	}
	
	/**
	 * 根据实体属性和RowBounds进行分页查询
	 *
	 * @param record    查询条件
	 * @param rowBounds 分页条件
	 * @return 记录集合
	 */
	public List<T> selectByRowBounds(T record, RowBounds rowBounds) {
		logger.info("'selectByRowBounds'条件分页查询: {}, {}", record, rowBounds);
		return mapper.selectByRowBounds(record, rowBounds);
	}
	
	/**
	 * 根据实体中的属性查询总数，查询条件使用等号
	 * @param record 查询条件
	 * @return 记录数
	 */
	public int selectCount(T record) {
		logger.info("'selectCount'查询满足条件的记录数: {}", record);
		return mapper.selectCount(record);
	}
	
	/**
	 * 根据Example条件进行查询总数
	 * @param example 查询条件
	 * @return 记录数
	 */
	public int selectCountByExample(Object example) {
		logger.info("'selectCountByExample'查询满足条件的记录数: {}", example);
		return mapper.selectCountByExample(example);
	}
	
	/**
	 * 根据实体中的属性进行查询，只能有一个返回值，有多个结果是抛出异常，查询条件使用等号
	 * @param record 查询条件
	 * @return 记录
	 */
	public T selectOne(T record) {
		logger.info("'selectOne'查询满足条件的单个记录: {}", record);
		return mapper.selectOne(record);
	}
	
	/**
	 * 根据Example条件进行查询
	 * @param example 查询条件
	 * @return 记录
	 */
	public T selectOneByExample(Object example) {
		logger.info("'selectOneByExample'查询满足条件的单个记录: {}", example);
		return mapper.selectOneByExample(example);
	}
	
	/**
	 * 根据Example条件更新实体`record`包含的全部属性，null值会被更新
	 * @param record  待更新数据
	 * @param example 更新条件
	 * @return 受影响行数
	 */
	public int updateByExample(T record, Object example) {
		logger.info("'updateByExample'根据example更新记录: {}, {}", example, record);
		return mapper.updateByExample(record, example);
	}
	
	/**
	 * 根据Example条件更新实体`record`包含的不是null的属性值
	 * @param record  待更新数据
	 * @param example 更新条件
	 * @return 受影响行数
	 */
	public int updateByExampleSelective(T record, Object example) {
		logger.info("'updateByExampleSelective'根据example更新非空字段: {}, {}", example, record);
		return mapper.updateByExampleSelective(record, example);
	}
	
	/**
	 * 根据主键更新实体全部字段，null值会被更新
	 * @param record 记录，包含主键
	 * @return 受影响行数
	 */
	public int updateByPrimaryKey(T record) {
		logger.info("'updateByPrimaryKey'根据主键更新全部字段: {}", record);
		return mapper.updateByPrimaryKey(record);
	}
	
	/**
	 * 根据主键更新属性不为null的值
	 * @param record 记录，包含主键
	 * @return 受影响行数
	 */
	public int updateByPrimaryKeySelective(T record) {
		logger.info("'updateByPrimaryKeySelective'根据主键更新非空字段: {}", record);
		return mapper.updateByPrimaryKeySelective(record);
	}
}
